package com.zyl.Ecs.auth.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.zyl.Ecs.auth.mapper.AccountMapper;
import com.zyl.Ecs.auth.mapper.AccountRoleMapper;
import com.zyl.Ecs.auth.mapper.RoleMapper;
import com.zyl.Ecs.auth.mapper.ext.AccountExtMapper;
import com.zyl.Ecs.auth.mapper.ext.RoleExtMapper;
import com.zyl.Ecs.auth.service.AccountService;
import com.zyl.Ecs.common.domain.auth.bean.Account;
import com.zyl.Ecs.common.domain.auth.bean.AccountRole;
import com.zyl.Ecs.common.domain.auth.bean.Role;
import com.zyl.Ecs.common.domain.auth.ext.AccountExt;
import com.zyl.Ecs.common.exception.EcsException;
import com.zyl.Ecs.common.response.ResultCode;
import com.zyl.Ecs.common.utils.CUtil;
import com.zyl.Ecs.common.utils.ObjectUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;


/**
* @version v1.0
* @Package: com.zyl.Ecs.auth.service.impl
* @ClassName: AccountRoleServiceImpl
* @Description 针对表【base_account_role】的数据库操作Service实现
* @Author 翟玉龙
* @Date 2024-12-04 16:36:41
*/

@Service
@RequiredArgsConstructor
public class AccountServiceImpl extends MPJBaseServiceImpl<AccountRoleMapper, AccountRole>
    implements AccountService {

    private final RoleMapper roleMapper;
    private final AccountMapper accountMapper;
    private final AccountRoleMapper accountRoleMapper;
    private final IService iService;
    private final AccountExtMapper accountExtMapper;
    private final RoleExtMapper roleExtMapper;

    /**
     * 添加账号角色
     * @param accountExt 账号角色信息
     * @return {@link AccountExt }
     * @throws EcsException 异常
     */
    @Override
    public AccountExt add(AccountExt accountExt) {
        /* 检查用户名是否重复 */
        String username = accountExt.getUsername();
        checkUserNameUnique(username, null);

        /* 检查密码并且设置加密数据 */
        String password = ObjectUtil.notHasText(accountExt.getPassword()) ? "123456" : accountExt.getPassword();
        accountExt
                .setPassword(CUtil.encrypt(password))
                /* 自动为用户生成注册时间（当前时间） */
                .setRegisterTime(LocalDateTime.now())
                .setStatus(0)
                .setDeleted(0);

        /* 执行写入 */
        accountMapper.insert(accountExt);

        /* 写入角色信息 */
        setRoles(accountExt.getId(), accountExt.getRoleIds(), false);

        /* 查询完整信息并返回 */
        return iService.fillRoles(accountExt, accountExt.getId(), true);
    }

    /**
     * 删除账号角色
     * @param id 账号角色id
     * @return {@link AccountExt }
     * @throws EcsException 异常
     */
    @Override
    public AccountExt delete(Integer id) throws EcsException {
        AccountExt accountExt = get(id);
        accountMapper.deleteById(id);
        return accountExt;
    }

    /**
     * 更新账号角色
     * @param accountExt 账号角色信息
     * @return {@link AccountExt }
     * @throws EcsException 异常
     */
    @Override
    public AccountExt update(AccountExt accountExt) throws EcsException{

        /* 校验id是否存在 */
        Integer id = accountExt.getId();
        internalGet(id);

        /* 校验名称是否重复 */
        String username = accountExt.getUsername();
        checkUserNameUnique(username, id);

        /* 如果修改了密码，则对密码进行加密 */
        String password = accountExt.getPassword();
        if (ObjectUtil.hasText(password)) {
            accountExt.setPassword(CUtil.encrypt(password));
        }

        /* 执行修改 */
        accountMapper.updateById(accountExt);

        /* 重设用户拥有的角色 */
        setRoles(id, accountExt.getRoleIds(), true);

        return accountExt;
    }

    /**
     * 获取账号角色列表
     * @return {@link List }<{@link AccountExt }>
     * @throws EcsException 异常
     */
    @Override
    public List<AccountExt> getList() throws EcsException{
        /* 查询全部用户信息（返回的是PO） */
        List<Account> accounts = accountMapper.selectList(null);
        if (ObjectUtil.isEmpty(accounts)) {
            return null;
        }
        /* 获取AccountExt基本信息 */
        MPJLambdaWrapper<AccountExt> queryA = new MPJLambdaWrapper<>();
        queryA
                .selectAll(AccountExt.class)
                .selectCollection(AccountRole.class, AccountExt::getRoleIds, map -> map
                        .result(AccountRole::getRoleId)
                )
                .leftJoin(AccountRole.class, AccountRole::getAccountId, AccountExt::getId)
                .orderByAsc(AccountRole::getRoleId);
        List<AccountExt> accountExtList = accountExtMapper.selectList(queryA);
        CUtil.logInfo(accountExtList.toString());
        /* 获取RoleExt基本信息 */
        for(AccountExt ext : accountExtList) {
            ext.setRoles(iService.fillRPs(ext));
        }
        return accountExtList;
    }

    /**
     * 检查用户名是否唯一
     * @param userName      用户名
     * @param id            用户id
     * @throws EcsException 异常
     */
    private void checkUserNameUnique(String userName, Integer id) throws EcsException{
        Account account = accountMapper.selectOne(Wrappers.<Account>lambdaQuery()
                .eq(Account::getUsername, userName));
        if (ObjectUtil.nonNull(account) && ObjectUtil.notEquals(account.getId(), id)) {
            throw new EcsException(ResultCode.ACCOUNT_USERNAME_DUPLICATE);
        }
    }

    /**
     * 为用户设置角色
     *
     * @param id           用户id
     * @param roleIds      角色id列表
     * @param deleteBefore 是否先删除已有角色，新增时不需要，修改时需要
     */
    private void setRoles(Integer id, List<Integer> roleIds, boolean deleteBefore) {
        /* 检查是否需要删除已存在角色 */
        if (deleteBefore) {
            accountRoleMapper.delete(Wrappers.<AccountRole>lambdaQuery()
                    .eq(AccountRole::getAccountId, id));
        }

        /* 检查角色列表是否为空 */
        if (ObjectUtil.isEmpty(roleIds)) {
            return;
        }

        /* 遍历角色id列表，写入用户角色关联数据 */
        roleIds.forEach(roleId -> {
            /* 校验角色是否存在 */
            Role role = roleMapper.selectById(roleId);
            if (ObjectUtil.isNull(role)) {
                throw new EcsException(ResultCode.ROLE_NOT_EXIST);
            }
            accountRoleMapper.insert(AccountRole.builder()
                    .accountId(id)
                    .roleId(roleId)
                    .build());
        });
    }

    /**
     * 获取账号扩展角色
     * @param id 账号角色id
     * @return {@link AccountExt }
     */
    private AccountExt get(Integer id) {
        Account account = internalGet(id);
        AccountExt ext = AccountExt.toExt(account);
        iService.fillRoles(ext, ext.getId(), true);
        return ext;
    }

    /**
     * 获取账号角色
     * @param id 账号角色id
     * @return {@link Account }
     */
    private Account internalGet(Integer id) {
        Account account = accountMapper.selectById(id);
        if (ObjectUtil.isNull(account)) {
            throw new EcsException(ResultCode.ACCOUNT_NOT_EXIST);
        }
        return account;
    }

}




